//
//  ViewController.swift
//  BWNetworkKit
//
//  Created by 1906457616@qq.com on 01/28/2022.
//  Copyright (c) 2022 1906457616@qq.com. All rights reserved.
//

import BWHUDKit
import BWNetworkKit
import BWListKit
import BWToolKit
import BWEmptyKit
import BWUIKit

extension Int64 {
    public enum SizeFormat {
        public static let bytes = "Bytes"
        public static let kb = "KB"
        public static let mb = "M"
        public static let gb = "G"
    }
    
    public var bw_bytesSized: String {
        let kb = self / 1024
        let mb = Double(self) / pow(1024, 2)
        let gb = Double(self) / pow(1024, 3)
        if gb >= 1 {
            return String(format: "%.2f\(SizeFormat.gb)", gb)
        }
        if mb >= 1 {
            return String(format: "%.2f\(SizeFormat.mb)", mb)
        }
        if kb >= 1 {
            return String(format: "%.2f\(SizeFormat.kb)", mb)
        }
        return "\(self)\(SizeFormat.bytes)"
    }
}

enum CustomEmpty {
    case json2ModelError
    case noMingju
    case noShiwen
}

extension Empty.Data {
    static func gushiwenRequestError(
        _ error: Request.Error,
        handler: BlockVoid?
    ) -> Self
    {
        var image: UIImage?
        switch error {
        case .responseError:
            image = .init(named: "empty_request-error")
        case .json2ModelError:
            image = .init(named: "empty_parse-error")
        default: break
        }
        
        return .init(styling: { empty in
            empty.label?.textColor = .systemRed
        }, image: image, tips: error.localizedDescription, action: .init(icon: UIImage(named: "ic_reload"), title: "重试", handler: handler))
    }
}

class SingleRequestVC: TableViewController {
    
    var gushiwens: [Shiwen] = []
    var mingjus: [Mingju] = []
    
    override func didLoad() {
        super.didLoad()
        
        Empty.binds([
            .init(senario: .requestFailed, data: .gushiwenRequestError(.unknown("数据请求失败，请重试"), handler: { [weak self] in
                self?.singleRequest()
            }))
        ], for: listAdapter)
        
        singleRequest()
    }
    
    @IBAction func downloadVideo(_ sender: Any) {
        var request: Request?
        request = Networker.request(
            api: API.File.downloadVideo(name: "HoneyBee_3840x2160_30fps_420_8bit_AVC_MP4.mp4"),
            progressing:
        { progress,object in
            HUD.dismiss(first: .loading)
            HUD.progress(
                .water,
                value: CGFloat(progress),
                text:
"""
\(Int(progress * 100))%\n
\(object!.completedUnitCount.bw_bytesSized) / \(object!.totalUnitCount.bw_bytesSized)
"""
                , canceller: { [weak request] in
                    guard let request = request else {
                        return
                    }
                    request.cancel()
                    HUD.dismiss(first: .loading)
                    HUD.toast(icon: .error, text: "Cancelled")
                })
        }, callback: { state in
            switch state {
            case .loading:
                HUD.loading()
            case .finished:
                HUD.dismissAll()
                print("finished")
            case .success:
                HUD.tips(.success, text: "下载完成")
            case .failed(let error):
                HUD.dismissAll()
                HUD.toast(error.localizedDescription)
            }
        })
    }
    
    @IBAction func singleRequest() {
        GushiwenRecommend.request(API.Gushiwen.recommend(page: 1))
        { [weak self] res in
            guard let self = self else {
                return
            }
            switch res {
            case .loading: HUD.loading()
            case .finished: HUD.dismissAll()

            case .success(let data):
                if data.mingjus.isEmpty,
                   let idx = self.listAdapter.index(of: self.minjuSection) {
                    Empty.showCell(for: self.listAdapter, section: idx, data: .init(image: .init(named: "empty_no-goods"), tips: "暂无名句"))
                }
                else {
                    self.mingjus = data.mingjus
                    self.reloadMinjus()
                }
                
                if data.gushiwens.isEmpty,
                   let idx = self.listAdapter.index(of: self.shiwenSection) {
                    Empty.showCell(for: self.listAdapter, section: idx, data: .init(image: .init(named: "empty_no-orders"), tips: "暂无诗句"))
                }
                else {
                    self.gushiwens = data.gushiwens
                    self.reloadShiwens()
                }
                
            case .failed(let error):
                guard !self.listAdapter.hasItems else {
                    HUD.toast(icon: .error, text: error.localizedDescription)
                    return
                }
                Empty.show(.gushiwenRequestError(error, handler: {
                    self.singleRequest()
                }), for: self.listAdapter)
            }
        }
    }
    
    func reloadData(){
        let data = BWListData(registers: [
            .init(style: .cell, xib: MinjuCell.RID),
            .init(style: .cell, xib: ShiwenCell.RID),
        ])
        data.sections = [
            minjuSection,
            shiwenSection
        ]
        listAdapter.data = data
    }
    
    lazy var minjuSection = BWListSection()
    func reloadMinjus(){
        minjuSection.header = .init(view: HeaderLabel(data: .init(title: "名句", itemsCount: mingjus.count)), height: 40)
        minjuSection.items = mingjus.map{
            .init(reuseId: MinjuCell.RID, height: UITableViewAutomaticDimension, data: $0, action: nil)
        }
        if let _ = listAdapter.index(of: minjuSection) {
            listAdapter.reload(sections: [minjuSection])
        }
        else {
            reloadData()
        }
    }
    
    lazy var shiwenSection = BWListSection()
    func reloadShiwens(){
        shiwenSection.header = .init(view: HeaderLabel(data: .init(title: "诗文", itemsCount: gushiwens.count)), height: 40)
        shiwenSection.items = gushiwens.map{
            .init(reuseId: ShiwenCell.RID, height: UITableViewAutomaticDimension, data: $0, action: nil)
        }
        if let _ = listAdapter.index(of: shiwenSection) {
            listAdapter.reload(sections: [shiwenSection])
        }
        else {
            reloadData()
        }
    }
    
    @IBAction func serialRequests() {
        Jumper.jump(.push(storyboard!.instantiateViewController(withIdentifier: "SerialRequestsVC"), animated: true))
    }
    @IBAction func groupRequests() {
        Jumper.jump(.push(storyboard!.instantiateViewController(withIdentifier: "GroupedRequestsVC"), animated: true))
    }
}

class HeaderLabel: UILabel {
    init(data: Header) {
        super.init(frame: .zero)
        
        text = data.title + "（\(data.itemsCount)）"
        backgroundColor = .systemRed
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}


struct Header {
    var title: String
    var itemsCount: Int
}

extension BWListAdapter {
    var hasItems: Bool {
        return (data?.totalItemsCount ?? 0) > 0
    }
}
